/*
 * @(#)DefaultCall.java $version 2010. 8. 11
 *
 * Copyright 2007-2010 NHN Corp. All rights Reserved. 
 * NHN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */

package com.nhncorp.usf.core.call;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

/**
 * {@link Call}의 기본 구현체.
 * 
 * @author Web Platform Development Team  
 */
public class DefaultCall implements Call {
	private static final long serialVersionUID = 4319188656024341193L;
	private String objectName;
	private String methodName;
	private List<Object> parameters = new ArrayList<Object>();

	/**
	 * <tt>objectName</tt>과 <tt>methodName</tt>이 아직 설정되지 않은 파라메터 목록이 없는
	 * 인스턴스를 생성한다.
	 */
	public DefaultCall() {
	}

	public String getObjectName() {
		return objectName;
	}

	/**
	 * 호출 대상 객체의 이름을 설정한다.
	 * <Br>
	 * <b>NullPointerException</b>발생
	 * <tt>objectName</tt>이 <tt>null</tt>일 때
	 * 
	 * @param objectName the object name
	 */
	public void setObjectName(String objectName) {
		if (objectName == null) {
			throw new NullPointerException("objectName");
		}

		this.objectName = objectName;
	}

	public String getMethodName() {
		return methodName;
	}

	/**
	 * 호출 대상 메소드의 이름을 설정한다.
	 * 
	 * <b>NullPointerException</b>발생 :
	 * <tt>methodName</tt>이 <tt>null</tt>일 때
	 * 
	 * @param methodName 호출할 methodName
	 */
	public void setMethodName(String methodName) {
		if (methodName == null) {
			throw new NullPointerException("methodName");
		}

		this.methodName = methodName;
	}

	public List<Object> getParameters() {
		return parameters;
	}

	/**
	 * 호출 대상에게 넘겨줄 파라메터의 목록을 설정한다. <tt>null</tt>을 제시하면 아무 파라메터도 넘기지 않는 것으로
	 * 설정한다.
	 * 
	 * @param parameters 호출할 method의 parameter <b>type Collection&lt ? &gt </b>
	 */
	public void setParameters(Collection< ? > parameters) {
		if (parameters == null) {
			this.parameters = Collections.unmodifiableList(Collections.emptyList());
		} else {
			this.parameters = Collections.unmodifiableList(new ArrayList<Object>(parameters));
		}
	}

	/**
	 * 호출 대상에게 넘겨줄 파라메터의 목록을 설정한다. <tt>null</tt>을 제시하면 아무 파라메터도 넘기지 않는 것으로
	 * 설정한다.
	 * 
	 * @param parameters 호출할 method의 parameter <b>type VARGS </b>
	 */
	public void setParameters(Object... parameters) {
		if (parameters == null) {
			this.parameters = Collections.unmodifiableList(Collections.emptyList());
		} else {
			List<Object> newParameters = new ArrayList<Object>(parameters.length);
			Collections.addAll(newParameters, parameters);
			this.parameters = Collections.unmodifiableList(newParameters);
		}
	}

	/**
	 * {@inheritDoc}
	 */
	public void validate() {
		if (objectName == null) {
			throw new IllegalStateException("objectName is not set.");
		}

		if (methodName == null) {
			throw new IllegalStateException("methodName is not set.");
		}
	}

	/**
	 * {@inheritDoc}
	 */
	public String toString() {
		return "call: " + getObjectName() + "#" + getMethodName() + "(" + getParameters() + ")";
	}

	/**
	 * {@inheritDoc}
	 */
	public boolean equals(Object object) {
		if (this == object) {
			return true;
		}
		if (!(object instanceof DefaultCall)) {
			return false;
		}

		DefaultCall that = (DefaultCall)object;

		if (methodName != null ? !methodName.equals(that.methodName) : that.methodName != null) {
			return false;
		}
		if (objectName != null ? !objectName.equals(that.objectName) : that.objectName != null) {
			return false;
		}
		if (parameters != null ? !parameters.equals(that.parameters) : that.parameters != null) {
			return false;
		}

		return true;
	}

	/**
	 * {@inheritDoc}
	 */
	public int hashCode() {
		int result = objectName != null ? objectName.hashCode() : 0;
		result = 31 * result + (methodName != null ? methodName.hashCode() : 0);
		result = 31 * result + (parameters != null ? parameters.hashCode() : 0);
		return result;
	}
}

